{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 机器读心术之神经网络与深度学习第11课书面作业\n",
    "学号：207567\n",
    "\n",
    "**书面作业：**  \n",
    "1. 阅读《Deep Residual Learning for Image Recognition》第4页右上角“Residual Network”一段，详细解释一下当用shortcut连接不同维度时的具体处理办法  \n",
    "2. 阅读《Batch Normalization Accelerating Deep Network Training by Reducing Internal Covariate Shift》，说一下BN具体是怎么回事？  \n",
    "3. 第9周作业中我们部署过matconvnet，里面有resnet的样例，跑起来测试看看，抓图实验过程  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第1题\n",
    "阅读《Deep Residual Learning for Image Recognition》第4页右上角“Residual Network”一段，详细解释一下当用shortcut连接不同维度时的具体处理办法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**答：**  \n",
    "首先来看一下维度不一样的情况如何，我们以论文中的一个具体的维度不同的shortcut来看看：  \n",
    "<img src=\"https://gitee.com/dotzhen/cloud-notes/raw/master/mind11-3.jpg\" alt=\"mind11-3\" style=\"zoom:50%;\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们看上图中（也就是论文中Figure 3）红色框为例，对于这个building block而言，输入是[n,64,56,56]（我们以[N,C,W,H]格式来看）,而输出是[n,128,28,28]。这个意思是输入数据有64个通道，每个通道的feature map的尺寸是$56\\times 56$，而输出是128个通道，每个通道上的feature map的尺寸是$28\\times 28$。  \n",
    "我们看到所谓不同维度，实际上有两层含义：  \n",
    "1. 不同的通道数，多出来的通道上的feature map如何赋值？  \n",
    "2. feature map大小不同，小了的feature map如何处理？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "论文中说了两种方法处理当shortcut连接两个不同维度数据时的处理：  \n",
    "1. **补零法**：论文中是这么描述的，\"*The shortcut still performs identity mapping, with extra zero entries padded for increasing dimensions. This option introduces no extra parameter.*\"。看完了以后还是有点信息的，我的理解如下：  \n",
    "   1. 这里提到”增加的维度“(increasing dimensions)，可以理解为多出来的通道，比如输出比输入多了64个通道，那这些通道上的feature maps全部填0；  \n",
    "   1. 对于前面64个通道的feature map变小了，可以用stride=2的采样来实现。  \n",
    "2. **投影法**：论文中是这么描述的，\"*The projection shortcut in Eqn.(2) is used to match dimensions (done by 1×1 convolutions). For both options, when the shortcuts go across feature maps of two sizes, they are performed with a stride of 2.*\"，对于这个操作我理解论文中说得比较清楚，这是一个$1\\times 1, stride=2$的卷积操作。结合论文《Identity Mappings in Deep Residual Networks》中给出的源码：https://github.com/KaimingHe/resnet-1k-layers 也能印证。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://gitee.com/dotzhen/cloud-notes/raw/master/mind11-4.jpg\" alt=\"mind11-4\" style=\"zoom:50%;\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个卷积示意如下：\n",
    "* 卷积是有参数的，会参与计算过程，对算力是有一定消耗的；  \n",
    "* stride=2在$1\\times 1$卷积中相当于间隔采样，会丢掉一半的信息。\n",
    "\n",
    "在论文4.1章节table 3中比较了上面方法1和方法2的办法，证明方法2比方法1要好。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://gitee.com/dotzhen/cloud-notes/raw/master/mind11-6.png\" alt=\"mind11-6\" style=\"zoom:50%;\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第2题\n",
    "阅读《Batch Normalization Accelerating Deep Network Training by Reducing Internal Covariate Shift》，说一下BN具体是怎么回事？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**答：**  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "论文中认为导致深度神经网络训练比较困难的原因是数据经过不同层的参数（这些参数会在训练的过程中变化）后其分布性了变化，而分布的变化会导致训练困难。我们通常知道如果训练集、测试集的数据分布不一致最后的预测会不好，另外由于使用了会饱和的激活函数，激活值很有可能改变分布进行入饱和区，导致梯度消息。同时Lecun有篇论文中也提到如果数据符合白化特征，即均值为0方差为1时，收敛性会更好。BN就是这样一种技术，它应用在mini-batch上，针对某一层的输入，将输入值的做均值为0，方差为1的变化，将这一操作融入到模型中（其实就是一个带bias的线性变化），融入模型的意思是梯度学习时能够看到这些参数并能一起学习。BN可以用在不同层中，如卷积层、全连接层中，通常应用在激活函数之前，同时可以在一个模型的多个层中都使用。在预测时，BN层中的参数不再更新。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第3题\n",
    "第9周作业中我们部署过matconvnet，里面有resnet的样例，跑起来测试看看，抓图实验过程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**答：**  \n",
    "提前下载了resnet-50-DAG预训练模型，用matconvnet运行预测，结果截图如下：  \n",
    "<img src=\"https://gitee.com/dotzhen/cloud-notes/raw/master/mind11-1.png\" alt=\"mind11-1\" style=\"zoom:50%;\" />"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
